compio_driver\sys\pal\windows/
mod.rs1use std::{fmt, io, ptr, task::Poll};
2
3pub use windows_sys::Win32::Networking::WinSock::CMSGHDR as CmsgHeader;
4use windows_sys::{
5 Win32::{
6 Foundation::{
7 ERROR_BROKEN_PIPE, ERROR_HANDLE_EOF, ERROR_IO_INCOMPLETE, ERROR_IO_PENDING,
8 ERROR_NETNAME_DELETED, ERROR_NO_DATA, ERROR_NOT_FOUND, ERROR_PIPE_CONNECTED,
9 ERROR_PIPE_NOT_CONNECTED, GetLastError,
10 },
11 Networking::WinSock::{SIO_GET_EXTENSION_FUNCTION_POINTER, WSAIoctl},
12 System::IO::{CancelIoEx, OVERLAPPED},
13 },
14 core::GUID,
15};
16
17use crate::syscall;
18
19mod_use::mod_use![fd];
20
21pub mod reexport {
22 pub use super::Overlapped;
23}
24
25#[repr(C)]
27pub struct Overlapped {
28 pub base: OVERLAPPED,
30 pub driver: RawFd,
32}
33
34impl fmt::Debug for Overlapped {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 f.debug_struct("Overlapped")
37 .field("base", &"OVERLAPPED")
38 .field("driver", &self.driver)
39 .finish()
40 }
41}
42
43impl Overlapped {
44 pub(crate) fn new(driver: RawFd) -> Self {
45 Self {
46 base: unsafe { std::mem::zeroed() },
47 driver,
48 }
49 }
50}
51
52unsafe impl Send for Overlapped {}
54unsafe impl Sync for Overlapped {}
55
56#[inline]
57pub fn winapi_result(transferred: u32) -> Poll<io::Result<usize>> {
58 let error = unsafe { GetLastError() };
59 assert_ne!(error, 0);
60 match error {
61 ERROR_IO_PENDING => Poll::Pending,
62 ERROR_IO_INCOMPLETE
63 | ERROR_NETNAME_DELETED
64 | ERROR_HANDLE_EOF
65 | ERROR_BROKEN_PIPE
66 | ERROR_PIPE_CONNECTED
67 | ERROR_PIPE_NOT_CONNECTED
68 | ERROR_NO_DATA => Poll::Ready(Ok(transferred as _)),
69 _ => Poll::Ready(Err(io::Error::from_raw_os_error(error as _))),
70 }
71}
72
73#[inline]
74pub fn win32_result(res: i32, transferred: u32) -> Poll<io::Result<usize>> {
75 if res == 0 {
76 winapi_result(transferred)
77 } else {
78 Poll::Ready(Ok(transferred as _))
79 }
80}
81
82#[inline]
83pub fn winsock_result(res: i32, transferred: u32) -> Poll<io::Result<usize>> {
84 if res != 0 {
85 winapi_result(transferred)
86 } else {
87 Poll::Ready(Ok(transferred as _))
88 }
89}
90
91#[inline]
92pub fn cancel(handle: RawFd, optr: *mut OVERLAPPED) -> io::Result<()> {
93 match syscall!(BOOL, CancelIoEx(handle as _, optr)) {
94 Ok(_) => Ok(()),
95 Err(e) => {
96 if e.raw_os_error() == Some(ERROR_NOT_FOUND as _) {
97 Ok(())
98 } else {
99 Err(e)
100 }
101 }
102 }
103}
104
105pub fn get_wsa_fn<F>(handle: RawFd, fguid: GUID) -> io::Result<Option<F>> {
106 let mut fptr = None;
107 let mut returned = 0;
108 syscall!(
109 SOCKET,
110 WSAIoctl(
111 handle as _,
112 SIO_GET_EXTENSION_FUNCTION_POINTER,
113 std::ptr::addr_of!(fguid).cast(),
114 std::mem::size_of_val(&fguid) as _,
115 std::ptr::addr_of_mut!(fptr).cast(),
116 std::mem::size_of::<F>() as _,
117 &mut returned,
118 ptr::null_mut(),
119 None,
120 )
121 )?;
122 Ok(fptr)
123}